#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
#include <string>

using namespace boost::asio;
namespace ssl = boost::asio::ssl;

class SSLServer {
private:
    io_context& io_context_;
    ssl::context& ssl_context_;
    ip::tcp::acceptor acceptor_;
    
public:
    SSLServer(io_context& io_context, ssl::context& ssl_context, short port)
        : io_context_(io_context),
          ssl_context_(ssl_context),
          acceptor_(io_context, ip::tcp::endpoint(ip::tcp::v4(), port)) {
        start_accept();
    }
    
private:
    void start_accept() {
        auto new_connection = std::make_shared<SSLConnection>(io_context_, ssl_context_);
        
        acceptor_.async_accept(new_connection->socket(),
            [this, new_connection](const boost::system::error_code& error) {
                if (!error) {
                    new_connection->start();
                }
                start_accept();
            });
    }
};

class SSLConnection : public std::enable_shared_from_this<SSLConnection> {
private:
    ssl::stream<ip::tcp::socket> ssl_socket_;
    std::array<char, 1024> buffer_;
    
public:
    SSLConnection(io_context& io_context, ssl::context& ssl_context)
        : ssl_socket_(io_context, ssl_context) {
    }
    
    ip::tcp::socket& socket() {
        return ssl_socket_.next_layer();
    }
    
    void start() {
        auto self(shared_from_this());
        ssl_socket_.async_handshake(ssl::stream_base::server,
            [this, self](const boost::system::error_code& error) {
                if (!error) {
                    read();
                }
            });
    }
    
private:
    void read() {
        auto self(shared_from_this());
        ssl_socket_.async_read_some(boost::asio::buffer(buffer_),
            [this, self](const boost::system::error_code& error, size_t bytes_transferred) {
                if (!error) {
                    std::cout << "Received: " << std::string(buffer_.data(), bytes_transferred) << std::endl;
                    write(bytes_transferred);
                }
            });
    }
    
    void write(size_t length) {
        auto self(shared_from_this());
        boost::asio::async_write(ssl_socket_, boost::asio::buffer(buffer_, length),
            [this, self](const boost::system::error_code& error, size_t /*bytes_transferred*/) {
                if (!error) {
                    read();
                }
            });
    }
};

int main() {
    try {
        io_context io_context;
        
        // 创建 SSL 上下文
        ssl::context ssl_context(ssl::context::tlsv12);
        
        // 设置服务器证书和私钥（需要实际的证书文件）
        // ssl_context.use_certificate_chain_file("server.crt");
        // ssl_context.use_private_key_file("server.key", ssl::context::pem);
        
        SSLServer server(io_context, ssl_context, 8443);
        
        std::cout << "SSL Server started on port 8443" << std::endl;
        io_context.run();
        
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
    
    return 0;
}